package top.fwpsl.script.base

/**
  * 方法和函数
  *
  * @author 风戏fw
  * @date 2020/11/26
  */
object MethodAndFunctionDemo {

  /**
    *
    * 在Scala中，方法(method)和函数(function)是两种不同的存在，
    * > 方法作为类的一部分存在，是这个类的行为动作，通过对象.方法来调用方法，
    * > 函数是一个对象，可以通过new关键字生成。
    * 方法：形参、返回值
    * 函数：入参、出参
    * 在函数式编程语言中，函数是“头等公民”，它可以像任何其他数据类型一样被传递和操作
    */

  // def 定义一个方法
  // main 方法名称
  // ()括号中为参数
  // args 形参名称
  // :冒号后面是参数类型
  // Array[String] Array:数组 String:数组的类型
  // Unit 返回值类型，Unit表示无返回值
  def main(args: Array[String]): Unit = {
    println("方法演练开始 >>>>>>>>>>>>>>")
    test1
    test1()
    test2
    // test2()报错不能加()
    test3("abc", 12)
    println("方法演练结束 >>>>>>>>>>>>>>")

    println("函数演练开始 >>>>>>>>>>>>>>")

    val res01 = test4("abc", 12)
    println("res01 = " + res01)
    val res02 = f1(1, 2)
    println("res02 = " + res02)
    val res03 = f2(1, 2)
    println("res03 = " + res03)

    // 调用m1方法，并传入f1函数
    val r1 = m1(f1)
    println(r1)

    // 调用m1方法，并传入f2函数
    val r2 = m1(f2)
    println(r2)

    // 调用m2方法，并传入f1函数
    val r3 = m2(f1, 2, 3)
    println(r3)

    // 调用m2方法，并传入f2函数
    val r4 = m2(f2, 2, 3)
    println(r4)
    println("函数演练结束 >>>>>>>>>>>>>>")
  }

  // def 定义一个方法
  //  test1方法名称 ()可以放参数，里面空的，无参
  // :冒号后面是参数类型
  // Unit 返回值类型，Unit表示无返回值
  def test1(): Unit = {
    println("test1() 这是一个无参的方法")
  }

  // def 定义一个方法
  // 省略小括号，省略掉返回值
  def test2 {
    println("test2 这是一个无参的方法")
  }

  def test3(a: String, b: Int) {
    println("test3这是一个有参的方法 " + a + " -- " + b)
  }

  def test4(a: String, b: Int): String = {
    def abc {
      println("adf")
    }
    //  调用函数
    abc
    234
    123
    "abc"
  }

  // 定义一个方法
  // 方法m1参数要求是一个函数，函数的参数必须是两个Int类型
  // 返回值类型也是Int类型
  def m1(f: (Int, Int) => Int): Int = {
    f(2, 6)
  }

  def m2(f: (Int, Int) => Int, x: Int, y: Int): Int = {
    f(x, y)
  }

  // 定义一个函数f1，参数是两个Int类型，返回值是一个Int类型
  val f1 = (x: Int, y: Int) => x + y
  // 再定义一个函数f2
  val f2 = (m: Int, n: Int) => m * n

}

